/**
 * Stats Class
 * Copyright (c) 2009 designmarco
 * @author Marco Di Giuseppe  |  http://designmarco.com
 * marco[at]designmarco[dot]com
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.designmarco.utils
{
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.system.System;
	import flash.utils.getTimer;
	/**
	 * Stats Class provides a visual representation of the FPS and System Memory.
	 * @example
		   <code>
		   import com.designmarco.utils.Stats; <br/>
		   var stats:Stats = new Stats(stage);
		   </code>
	 */
	public class Stats extends Sprite
	{
		private static var instance:Stats;
		private var fps:int;
		private var frames:int;
		private var counter:int;
		private var lastFrame:int;
		private var currentFrame:int;
		private var timeDisplay:TextField;
		private var holder:Sprite;
		private var _stage:Stage;

		/**
		 * Construct an Instance of the Stats Class
		 * @param	stage	root stage
		 * @param	auto	if processing will start right away
		 */
		public function Stats(stage:Stage, auto:Boolean = true)
		{
			if (instance) return;
			
			instance = this;
			_stage = stage;
			init(auto);
		}
		
		/**
		 * Initialize Stats Properties
		 * @param	b	autoplay if true
		 */
		private function init(b:Boolean):void
		{
			var format:TextFormat = new TextFormat();
			format.align = "right";
			format.color = 0x000000;
			format.size = 13;
			format.font = "sans";
			
		    holder = new Sprite();
			holder.graphics.beginFill(0xFFFFFF, 0.50);
			holder.graphics.drawRect(0, 0, 96, 18);
		
			timeDisplay = new TextField();
			timeDisplay.x = -10;
			timeDisplay.selectable = false;
			timeDisplay.defaultTextFormat = format;
			timeDisplay.text = "initializing";
			holder.addChild(timeDisplay);
			
			_stage.addChild(holder);
			
			if(b) start();
		  }
	
		  /**
		   * Begin Monitoring Stats
		   */
		  public function start():void
		  {
			  _stage.addEventListener(Event.ENTER_FRAME, tick, false, 0, true);
		  }
		
		  /**
		   * End Monitoring Stats
		   */
		  public function stop():void
		  {
			  _stage.removeEventListener(Event.ENTER_FRAME, tick);
		  }
		
		  /**
		   * Update Stats Performance
		   * @param	event
		   */
		  public function tick(event:Event = null):void
		  {
			currentFrame 	= getTimer();
			frames 			= currentFrame - lastFrame;
			fps 			= 1000 / (frames);
			
			counter += frames;
			
			if (counter > 1000)
			{
				timeDisplay.text = fps + " fps | " + (System.totalMemory / 1024 / 1024).toFixed(1) + " mb";
				counter = 0;
			}
			
			lastFrame = currentFrame;
		  }
		
		 /**
		  * Destroy Method
		  */
		  public function kill():void
		  {
			  stop();
			  _stage.removeChild(holder);
			  fps = frames = currentFrame = counter = lastFrame = NaN;
			  holder		= null;
			  timeDisplay 	= null;
			  instance 		= null;
			  _stage 		= null;
			
		}
	}
}
